{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 已经学习 Python 数据分析的编程基础\n",
    "#  因为数据分析师和科学家总是在数据规整和准备上花费大量时间，重点在于掌握这些功能。\n",
    "\n",
    "# 开发模型选用什么库取决于应用本身。\n",
    "# 许多统计问题可以用简单方法解决，比如普通的最小二乘回归，其它问题可能需要复杂的机器学习方法。\n",
    "\n",
    "# 幸运的是， Python 已经成为了运用这些分析方法的语言之一， 可以探索许多工具\n",
    "\n",
    "# 会回顾一些 pandas 的特点， 在你胶着于 pandas 数据规整和模型拟合和评分时， 它们可能派上用场\n",
    "#   然后简短介绍两个流行的建模工具， statsmodels 和 scikit-learn\n",
    "# 这二者每个都值得再写一本书， 不做全面的介绍， 而是建议学习两个项目的线上文档"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>x0</th>\n",
       "      <th>x1</th>\n",
       "      <th>y</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>0.01</td>\n",
       "      <td>-1.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>-0.01</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>0.25</td>\n",
       "      <td>3.6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>-4.10</td>\n",
       "      <td>1.3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>0.00</td>\n",
       "      <td>-2.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   x0    x1    y\n",
       "0   1  0.01 -1.5\n",
       "1   2 -0.01  0.0\n",
       "2   3  0.25  3.6\n",
       "3   4 -4.10  1.3\n",
       "4   5  0.00 -2.0"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# pandas与模型代码的接口\n",
    "\n",
    "# 模型开发的通常工作流是使用 pandas 进行数据加载和清洗， 然后切换到建模库进行建模。\n",
    "\n",
    "# 开发模型的重要一环是机器学习中的 “特征工程”\n",
    "# 它可以描述从原始数据集中提取信息的任何数据转换或分析， 这些数据集可能在建模中有用\n",
    "\n",
    "# pandas 学习的 数据聚合 和 GroupBy 工具常用于特征工程中\n",
    "\n",
    "# 优秀的特征工程超出了范围，尽量直白地介绍一些用于数据操作和建模切换的方法\n",
    "\n",
    "# pandas 与其它分析库通常是靠 NumPy 的数组联系起来的\n",
    "# 将 DataFrame 转换为 NumPy 数组， 可以使用 .values 属性\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "\n",
    "data = pd.DataFrame({'x0': [1, 2, 3, 4, 5],\n",
    "                     'x1': [0.01, -0.01, 0.25, -4.1, 0.],\n",
    "                     'y': [-1.5, 0., 3.6, 1.3, -2.]})\n",
    "\n",
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Index(['x0', 'x1', 'y'], dtype='object')"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.  ,  0.01, -1.5 ],\n",
       "       [ 2.  , -0.01,  0.  ],\n",
       "       [ 3.  ,  0.25,  3.6 ],\n",
       "       [ 4.  , -4.1 ,  1.3 ],\n",
       "       [ 5.  ,  0.  , -2.  ]])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 要转换回 DataFrame， 可以传递一个二维 ndarray， 可带有列名：\n",
    "df2 = pd.DataFrame(data.values, columns=['one', 'two', 'three'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>one</th>\n",
       "      <th>two</th>\n",
       "      <th>three</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1.0</td>\n",
       "      <td>0.01</td>\n",
       "      <td>-1.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2.0</td>\n",
       "      <td>-0.01</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3.0</td>\n",
       "      <td>0.25</td>\n",
       "      <td>3.6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4.0</td>\n",
       "      <td>-4.10</td>\n",
       "      <td>1.3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5.0</td>\n",
       "      <td>0.00</td>\n",
       "      <td>-2.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   one   two  three\n",
       "0  1.0  0.01   -1.5\n",
       "1  2.0 -0.01    0.0\n",
       "2  3.0  0.25    3.6\n",
       "3  4.0 -4.10    1.3\n",
       "4  5.0  0.00   -2.0"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>x0</th>\n",
       "      <th>x1</th>\n",
       "      <th>y</th>\n",
       "      <th>strings</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>0.01</td>\n",
       "      <td>-1.5</td>\n",
       "      <td>a</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>-0.01</td>\n",
       "      <td>0.0</td>\n",
       "      <td>b</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>0.25</td>\n",
       "      <td>3.6</td>\n",
       "      <td>c</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>-4.10</td>\n",
       "      <td>1.3</td>\n",
       "      <td>d</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>0.00</td>\n",
       "      <td>-2.0</td>\n",
       "      <td>e</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   x0    x1    y strings\n",
       "0   1  0.01 -1.5       a\n",
       "1   2 -0.01  0.0       b\n",
       "2   3  0.25  3.6       c\n",
       "3   4 -4.10  1.3       d\n",
       "4   5  0.00 -2.0       e"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 笔记： 最好当数据是均匀的时候使用 .values属性\n",
    "#     例如， 全是数值类型。 如果数据是不均匀的， 结果会是 Python 对象的 ndarray：\n",
    "df3 = data.copy()\n",
    "df3['strings'] = ['a', 'b', 'c', 'd', 'e']\n",
    "df3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 0.01, -1.5, 'a'],\n",
       "       [2, -0.01, 0.0, 'b'],\n",
       "       [3, 0.25, 3.6, 'c'],\n",
       "       [4, -4.1, 1.3, 'd'],\n",
       "       [5, 0.0, -2.0, 'e']], dtype=object)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df3.values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.  ,  0.01],\n",
       "       [ 2.  , -0.01],\n",
       "       [ 3.  ,  0.25],\n",
       "       [ 4.  , -4.1 ],\n",
       "       [ 5.  ,  0.  ]])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 对于一些模型， 可能只想使用列的子集\n",
    "# 建议使用 loc， 用 values 作索引：\n",
    "model_cols = ['x0', 'x1']\n",
    "data.loc[:, model_cols].values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>x0</th>\n",
       "      <th>x1</th>\n",
       "      <th>y</th>\n",
       "      <th>category</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>0.01</td>\n",
       "      <td>-1.5</td>\n",
       "      <td>a</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>-0.01</td>\n",
       "      <td>0.0</td>\n",
       "      <td>b</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>0.25</td>\n",
       "      <td>3.6</td>\n",
       "      <td>a</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>-4.10</td>\n",
       "      <td>1.3</td>\n",
       "      <td>a</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>0.00</td>\n",
       "      <td>-2.0</td>\n",
       "      <td>b</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   x0    x1    y category\n",
       "0   1  0.01 -1.5        a\n",
       "1   2 -0.01  0.0        b\n",
       "2   3  0.25  3.6        a\n",
       "3   4 -4.10  1.3        a\n",
       "4   5  0.00 -2.0        b"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 一些库原生支持 pandas， 会自动完成工作： 从 DataFrame 转换到 NumPy， 将模型的参数名添加到输出表的 列 或 Series\n",
    "#   其它情况， 可以手工进行 “元数据管理”\n",
    "\n",
    "# 学习了 pandas 的 Categorical 类型和 pandas.get_dummies 函数\n",
    "# 假设数据集中有一个非数值列：\n",
    "data['category'] = pd.Categorical(['a', 'b', 'a', 'a', 'b'],\n",
    "                                  categories=['a', 'b'])\n",
    "\n",
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>x0</th>\n",
       "      <th>x1</th>\n",
       "      <th>y</th>\n",
       "      <th>category_a</th>\n",
       "      <th>category_b</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>0.01</td>\n",
       "      <td>-1.5</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>-0.01</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>0.25</td>\n",
       "      <td>3.6</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>-4.10</td>\n",
       "      <td>1.3</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>0.00</td>\n",
       "      <td>-2.0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   x0    x1    y  category_a  category_b\n",
       "0   1  0.01 -1.5           1           0\n",
       "1   2 -0.01  0.0           0           1\n",
       "2   3  0.25  3.6           1           0\n",
       "3   4 -4.10  1.3           1           0\n",
       "4   5  0.00 -2.0           0           1"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 如果想替换 category 列为虚变量，可以创建虚变量， 删除 category 列， 然后添加到结果：\n",
    "dummies = pd.get_dummies(data.category, prefix='category')\n",
    "\n",
    "data_with_dummies = data.drop('category', axis=1).join(dummies)\n",
    "\n",
    "data_with_dummies\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>x0</th>\n",
       "      <th>x1</th>\n",
       "      <th>y</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>0.01</td>\n",
       "      <td>-1.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>-0.01</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>0.25</td>\n",
       "      <td>3.6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>-4.10</td>\n",
       "      <td>1.3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>0.00</td>\n",
       "      <td>-2.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   x0    x1    y\n",
       "0   1  0.01 -1.5\n",
       "1   2 -0.01  0.0\n",
       "2   3  0.25  3.6\n",
       "3   4 -4.10  1.3\n",
       "4   5  0.00 -2.0"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 用虚变量拟合某些统计模型会有一些细微差别\n",
    "#  当不只有数字列时， 使用 Patsy 可能更简单， 更不容易出错。\n",
    "\n",
    "# 用 Patsy 创建模型描述\n",
    "\n",
    "# Patsy 是 Python 的一个库， 使用简短的字符串 “公式语法” 描述统计模型（尤其是线性模型），\n",
    "# 可能是受到了 R 和 S 统计编程语言的公式语法的启发。\n",
    "\n",
    "# Patsy 适合描述 statsmodels 的线性模型，因此会关注于它的主要特点，让你尽快掌握\n",
    "#  Patsy 的公式是一个特殊的字符串语法， 如下所示：\n",
    "\n",
    "# y ~ x0 + x1\n",
    "\n",
    "# a+b 不是将 a 与 b 相加的意思， 而是为模型创建的设计矩阵\n",
    "#   patsy.dmatrices 函数接收一个公式字符串和一个数据集（可以是 DataFrame 或数组的字典），为线性模型创建设计矩阵：\n",
    "data = pd.DataFrame({\n",
    "                    'x0': [1, 2, 3, 4, 5],\n",
    "                    'x1': [0.01, -0.01, 0.25, -4.1, 0.],\n",
    "                    'y': [-1.5, 0., 3.6, 1.3, -2.]})\n",
    "\n",
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DesignMatrix with shape (5, 1)\n",
       "     y\n",
       "  -1.5\n",
       "   0.0\n",
       "   3.6\n",
       "   1.3\n",
       "  -2.0\n",
       "  Terms:\n",
       "    'y' (column 0)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import patsy\n",
    "\n",
    "y, X = patsy.dmatrices('y ~ x0 + x1', data)\n",
    "\n",
    "y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DesignMatrix with shape (5, 3)\n",
       "  Intercept  x0     x1\n",
       "          1   1   0.01\n",
       "          1   2  -0.01\n",
       "          1   3   0.25\n",
       "          1   4  -4.10\n",
       "          1   5   0.00\n",
       "  Terms:\n",
       "    'Intercept' (column 0)\n",
       "    'x0' (column 1)\n",
       "    'x1' (column 2)"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-1.5],\n",
       "       [ 0. ],\n",
       "       [ 3.6],\n",
       "       [ 1.3],\n",
       "       [-2. ]])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 这些 Patsy 的 DesignMatrix 实例是 NumPy 的 ndarray， 带有附加元数据：\n",
    "np.asarray(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.  ,  1.  ,  0.01],\n",
       "       [ 1.  ,  2.  , -0.01],\n",
       "       [ 1.  ,  3.  ,  0.25],\n",
       "       [ 1.  ,  4.  , -4.1 ],\n",
       "       [ 1.  ,  5.  ,  0.  ]])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.asarray(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DesignMatrix with shape (5, 2)\n",
       "  x0     x1\n",
       "   1   0.01\n",
       "   2  -0.01\n",
       "   3   0.25\n",
       "   4  -4.10\n",
       "   5   0.00\n",
       "  Terms:\n",
       "    'x0' (column 0)\n",
       "    'x1' (column 1)"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 可能想 Intercept 是哪里来的\n",
    "#  这是线性模型（比如普通最小二乘回归） 的惯例用法\n",
    "# 添加 +0 到模型可以不显示 intercept：\n",
    "patsy.dmatrices('y ~ x0 + x1 + 0', data)[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Anaconda\\lib\\site-packages\\ipykernel_launcher.py:2: FutureWarning: `rcond` parameter will change to the default of machine precision times ``max(M, N)`` where M and N are the input matrix dimensions.\n",
      "To use the future default and silence this warning we advise to pass `rcond=None`, to keep using the old, explicitly pass `rcond=-1`.\n",
      "  \n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([[ 0.31290976],\n",
       "       [-0.07910564],\n",
       "       [-0.26546384]])"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Patsy 对象可以直接传递到算法（比如 numpy.linalg.lstsq）中， 它执行普通最小二乘回归：\n",
    "coef, resid, _, _ = np.linalg.lstsq(X, y)\n",
    "\n",
    "coef"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Intercept    0.312910\n",
       "x0          -0.079106\n",
       "x1          -0.265464\n",
       "dtype: float64"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "coef = pd.Series(coef.squeeze(), index=X.design_info.column_names)\n",
    "\n",
    "coef"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DesignMatrix with shape (5, 3)\n",
       "  Intercept  x0  np.log(np.abs(x1) + 1)\n",
       "          1   1                 0.00995\n",
       "          1   2                 0.00995\n",
       "          1   3                 0.22314\n",
       "          1   4                 1.62924\n",
       "          1   5                 0.00000\n",
       "  Terms:\n",
       "    'Intercept' (column 0)\n",
       "    'x0' (column 1)\n",
       "    'np.log(np.abs(x1) + 1)' (column 2)"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 用 Patsy 公式进行数据转换\n",
    "# 可以将 Python 代码与 patsy 公式结合。\n",
    "# 在评估公式时， 库将尝试查找在封闭作用域内使用的函数：\n",
    "y, X = patsy.dmatrices('y ~ x0 + np.log(np.abs(x1) + 1)', data)\n",
    "\n",
    "X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DesignMatrix with shape (5, 3)\n",
       "  Intercept  standardize(x0)  center(x1)\n",
       "          1         -1.41421        0.78\n",
       "          1         -0.70711        0.76\n",
       "          1          0.00000        1.02\n",
       "          1          0.70711       -3.33\n",
       "          1          1.41421        0.77\n",
       "  Terms:\n",
       "    'Intercept' (column 0)\n",
       "    'standardize(x0)' (column 1)\n",
       "    'center(x1)' (column 2)"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 常见的变量转换包括标准化（平均值为0， 方差为1） 和中心化（减去平均值）\n",
    "# Patsy 有内置的函数进行这样的工作：\n",
    "y, X = patsy.dmatrices('y ~ standardize(x0) + center(x1)', data)\n",
    "\n",
    "X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[DesignMatrix with shape (4, 3)\n",
       "   Intercept  standardize(x0)  center(x1)\n",
       "           1          2.12132        3.87\n",
       "           1          2.82843        0.27\n",
       "           1          3.53553        0.77\n",
       "           1          4.24264        3.07\n",
       "   Terms:\n",
       "     'Intercept' (column 0)\n",
       "     'standardize(x0)' (column 1)\n",
       "     'center(x1)' (column 2)]"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 作为建模的一步， 可能拟合模型到一个数据集， 然后用另一个数据集评估模型\n",
    "#    另一个数据集可能是剩余的部分或是新数据。 \n",
    "# 当执行中心化和标准化转变， 用新数据进行预测要格外小心。 因为必须使用平均值或标准差转换新数据集，这也称作状态转换\n",
    "\n",
    "# patsy.build_design_matrices 函数可以使用原始样本数据集的保存信息， 来转换新数据，\n",
    "new_data = pd.DataFrame({\n",
    "                         'x0': [6, 7, 8, 9],\n",
    "                         'x1': [3.1, -0.5, 0, 2.3],\n",
    "                         'y': [1, 2, 3, 4]})\n",
    "\n",
    "new_X = patsy.build_design_matrices([X.design_info], new_data)\n",
    "\n",
    "new_X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DesignMatrix with shape (5, 2)\n",
       "  Intercept  I(x0 + x1)\n",
       "          1        1.01\n",
       "          1        1.99\n",
       "          1        3.25\n",
       "          1       -0.10\n",
       "          1        5.00\n",
       "  Terms:\n",
       "    'Intercept' (column 0)\n",
       "    'I(x0 + x1)' (column 1)"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 因为 Patsy 中的 加号 不是加法的意义， 当按照名称将数据集的列相加时， 你必须用特殊I函数将它们封装起来：\n",
    "y, X = patsy.dmatrices('y ~ I(x0 + x1)', data)\n",
    "\n",
    "X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DesignMatrix with shape (8, 2)\n",
       "  Intercept  key1[T.b]\n",
       "          1          0\n",
       "          1          0\n",
       "          1          1\n",
       "          1          1\n",
       "          1          0\n",
       "          1          1\n",
       "          1          0\n",
       "          1          1\n",
       "  Terms:\n",
       "    'Intercept' (column 0)\n",
       "    'key1' (column 1)"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Patsy 的 patsy.builtins 模块还有一些其它的内置转换, 请查看线上文档\n",
    "\n",
    "\n",
    "# 分类数据 和 Patsy\n",
    "\n",
    "# 非数值数据可以用多种方式转换为模型设计矩阵\n",
    "#    完整的讲解超出了本书，最好和统计课一起学习\n",
    "\n",
    "# 当在 Patsy 公式中使用非数值数据， 它们会默认转换为虚变量\n",
    "#   如果有截距， 会去掉一个， 避免共线性：\n",
    "data = pd.DataFrame({\n",
    "                     'key1': ['a', 'a', 'b', 'b', 'a', 'b', 'a', 'b'],\n",
    "                     'key2': [0, 1, 0, 1, 0, 1, 0, 0],\n",
    "                     'v1': [1, 2, 3, 4, 5, 6, 7, 8],\n",
    "                     'v2': [-1, 0, 2.5, -0.5, 4.0, -1.2, 0.2, -1.7]})\n",
    "\n",
    "y, X = patsy.dmatrices('v2 ~ key1', data)\n",
    "\n",
    "X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DesignMatrix with shape (8, 2)\n",
       "  key1[a]  key1[b]\n",
       "        1        0\n",
       "        1        0\n",
       "        0        1\n",
       "        0        1\n",
       "        1        0\n",
       "        0        1\n",
       "        1        0\n",
       "        0        1\n",
       "  Terms:\n",
       "    'key1' (columns 0:2)"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 如果从模型中忽略截距， 每个分类值的列都会包括在设计矩阵的模型中：\n",
    "y, X = patsy.dmatrices('v2 ~ key1 + 0', data)\n",
    "\n",
    "X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DesignMatrix with shape (8, 2)\n",
       "  Intercept  C(key2)[T.1]\n",
       "          1             0\n",
       "          1             1\n",
       "          1             0\n",
       "          1             1\n",
       "          1             0\n",
       "          1             1\n",
       "          1             0\n",
       "          1             0\n",
       "  Terms:\n",
       "    'Intercept' (column 0)\n",
       "    'C(key2)' (column 1)"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用 C函数， 数值列可以截取为分类量：\n",
    "y, X = patsy.dmatrices('v2 ~ C(key2)', data)\n",
    "\n",
    "X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>key1</th>\n",
       "      <th>key2</th>\n",
       "      <th>v1</th>\n",
       "      <th>v2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>a</td>\n",
       "      <td>zero</td>\n",
       "      <td>1</td>\n",
       "      <td>-1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>a</td>\n",
       "      <td>one</td>\n",
       "      <td>2</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>b</td>\n",
       "      <td>zero</td>\n",
       "      <td>3</td>\n",
       "      <td>2.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>b</td>\n",
       "      <td>one</td>\n",
       "      <td>4</td>\n",
       "      <td>-0.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>a</td>\n",
       "      <td>zero</td>\n",
       "      <td>5</td>\n",
       "      <td>4.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>b</td>\n",
       "      <td>one</td>\n",
       "      <td>6</td>\n",
       "      <td>-1.2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>a</td>\n",
       "      <td>zero</td>\n",
       "      <td>7</td>\n",
       "      <td>0.2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>b</td>\n",
       "      <td>zero</td>\n",
       "      <td>8</td>\n",
       "      <td>-1.7</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  key1  key2  v1   v2\n",
       "0    a  zero   1 -1.0\n",
       "1    a   one   2  0.0\n",
       "2    b  zero   3  2.5\n",
       "3    b   one   4 -0.5\n",
       "4    a  zero   5  4.0\n",
       "5    b   one   6 -1.2\n",
       "6    a  zero   7  0.2\n",
       "7    b  zero   8 -1.7"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 当在模型中使用多个分类名， 事情就会变复杂， 因为会包括 key1:key2 形式的相交部分， 它可以用在方差（ANOVA） 模型分析中：\n",
    "data['key2'] = data['key2'].map({0: 'zero', 1: 'one'})\n",
    "\n",
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DesignMatrix with shape (8, 3)\n",
       "  Intercept  key1[T.b]  key2[T.zero]\n",
       "          1          0             1\n",
       "          1          0             0\n",
       "          1          1             1\n",
       "          1          1             0\n",
       "          1          0             1\n",
       "          1          1             0\n",
       "          1          0             1\n",
       "          1          1             1\n",
       "  Terms:\n",
       "    'Intercept' (column 0)\n",
       "    'key1' (column 1)\n",
       "    'key2' (column 2)"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y, X = patsy.dmatrices('v2 ~ key1 + key2', data)\n",
    "\n",
    "X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DesignMatrix with shape (8, 4)\n",
       "  Intercept  key1[T.b]  key2[T.zero]  key1[T.b]:key2[T.zero]\n",
       "          1          0             1                       0\n",
       "          1          0             0                       0\n",
       "          1          1             1                       1\n",
       "          1          1             0                       0\n",
       "          1          0             1                       0\n",
       "          1          1             0                       0\n",
       "          1          0             1                       0\n",
       "          1          1             1                       1\n",
       "  Terms:\n",
       "    'Intercept' (column 0)\n",
       "    'key1' (column 1)\n",
       "    'key2' (column 2)\n",
       "    'key1:key2' (column 3)"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y, X = patsy.dmatrices('v2 ~ key1 + key2 + key1:key2', data)\n",
    "\n",
    "X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Patsy 提供转换分类数据的其它方法， 包括以特定顺序转换。 请参阅线上文档"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-0.12946849, -1.21275292,  0.50422488],\n",
       "       [ 0.30291036, -0.43574176, -0.25417986],\n",
       "       [-0.32852189, -0.02530153,  0.13835097],\n",
       "       [-0.35147471, -0.71960511, -0.25821463],\n",
       "       [ 1.2432688 , -0.37379916, -0.52262905]])"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# statsmodels 介绍\n",
    "\n",
    "# statsmodels 是 Python 进行拟合多种统计模型、 进行统计试验和数据探索可视化的库。\n",
    "# Statsmodels 包含许多经典的统计方法， 但没有贝叶斯方法和机器学习模型。\n",
    "# statsmodels包含的模型有：\n",
    "#    - 线性模型， 广义线性模型和健壮线性模型\n",
    "#    - 线性混合效应模型\n",
    "#    - 方差（ANOVA） 方法分析\n",
    "#    - 时间序列过程和状态空间模型\n",
    "#    - 广义矩估计\n",
    "\n",
    "# 下面， 使用一些基本的 statsmodels 工具， 探索 Patsy 公式和 pandas DataFrame对象如何使用模型接口\n",
    "\n",
    "# 估计线性模型\n",
    "# statsmodels 有多种线性回归模型， 包括从基本（比如普通最小二乘） 到复杂（比如迭代加权最小二乘法） \n",
    "\n",
    "# statsmodels 的线性模型有两种不同的接口： 基于数组和基于公式。 它们可以通过API模块引入：\n",
    "import statsmodels.api as sm\n",
    "import statsmodels.formula.api as smf\n",
    "\n",
    "# 为了展示它们的使用方法， 我们从一些随机数据生成一个线性模型：\n",
    "def dnorm(mean, variance, size=1):\n",
    "    if isinstance(size, int):\n",
    "        size = size,\n",
    "    return mean + np.sqrt(variance) * np.random.randn(*size)\n",
    "\n",
    "# For reproducibility\n",
    "np.random.seed(12345)\n",
    "\n",
    "N = 100\n",
    "\n",
    "X = np.c_[dnorm(0, 0.4, size=N),\n",
    "          dnorm(0, 0.6, size=N),\n",
    "          dnorm(0, 0.2, size=N)]\n",
    "\n",
    "eps = dnorm(0, 0.1, size=N)\n",
    "\n",
    "beta = [0.1, 0.3, 0.5]\n",
    "\n",
    "y = np.dot(X, beta) + eps\n",
    "\n",
    "# 使用了 “真实” 模型和 可知参数 beta\n",
    "# 此时， dnorm 可用来生成正态分布数据， 带有特定均值和方差。 现在有\n",
    "X[:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0.42786349, -0.67348041, -0.09087764, -0.48949442, -0.12894109])"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y[:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.        , -0.12946849, -1.21275292,  0.50422488],\n",
       "       [ 1.        ,  0.30291036, -0.43574176, -0.25417986],\n",
       "       [ 1.        , -0.32852189, -0.02530153,  0.13835097],\n",
       "       [ 1.        , -0.35147471, -0.71960511, -0.25821463],\n",
       "       [ 1.        ,  1.2432688 , -0.37379916, -0.52262905]])"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 像之前 Patsy 看到的， 线性模型通常要拟合一个截距\n",
    "# sm.add_constant 函数可以添加一个截距的列到现存的矩阵：\n",
    "X_model = sm.add_constant(X)\n",
    "\n",
    "X_model[:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.17826108, 0.22303962, 0.50095093])"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# sm.OLS 类可以拟合一个普通最小二乘回归\n",
    "model = sm.OLS(y, X)\n",
    "\n",
    "# 这个模型的 fit 方法返回了一个回归结果对象， 它包含估计的模型参数和其它内容：\n",
    "results = model.fit()\n",
    "\n",
    "results.params"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table class=\"simpletable\">\n",
       "<caption>OLS Regression Results</caption>\n",
       "<tr>\n",
       "  <th>Dep. Variable:</th>            <td>y</td>        <th>  R-squared (uncentered):</th>      <td>   0.430</td>\n",
       "</tr>\n",
       "<tr>\n",
       "  <th>Model:</th>                   <td>OLS</td>       <th>  Adj. R-squared (uncentered):</th> <td>   0.413</td>\n",
       "</tr>\n",
       "<tr>\n",
       "  <th>Method:</th>             <td>Least Squares</td>  <th>  F-statistic:       </th>          <td>   24.42</td>\n",
       "</tr>\n",
       "<tr>\n",
       "  <th>Date:</th>             <td>Fri, 26 Jun 2020</td> <th>  Prob (F-statistic):</th>          <td>7.44e-12</td>\n",
       "</tr>\n",
       "<tr>\n",
       "  <th>Time:</th>                 <td>17:44:46</td>     <th>  Log-Likelihood:    </th>          <td> -34.305</td>\n",
       "</tr>\n",
       "<tr>\n",
       "  <th>No. Observations:</th>      <td>   100</td>      <th>  AIC:               </th>          <td>   74.61</td>\n",
       "</tr>\n",
       "<tr>\n",
       "  <th>Df Residuals:</th>          <td>    97</td>      <th>  BIC:               </th>          <td>   82.42</td>\n",
       "</tr>\n",
       "<tr>\n",
       "  <th>Df Model:</th>              <td>     3</td>      <th>                     </th>              <td> </td>   \n",
       "</tr>\n",
       "<tr>\n",
       "  <th>Covariance Type:</th>      <td>nonrobust</td>    <th>                     </th>              <td> </td>   \n",
       "</tr>\n",
       "</table>\n",
       "<table class=\"simpletable\">\n",
       "<tr>\n",
       "   <td></td>     <th>coef</th>     <th>std err</th>      <th>t</th>      <th>P>|t|</th>  <th>[0.025</th>    <th>0.975]</th>  \n",
       "</tr>\n",
       "<tr>\n",
       "  <th>x1</th> <td>    0.1783</td> <td>    0.053</td> <td>    3.364</td> <td> 0.001</td> <td>    0.073</td> <td>    0.283</td>\n",
       "</tr>\n",
       "<tr>\n",
       "  <th>x2</th> <td>    0.2230</td> <td>    0.046</td> <td>    4.818</td> <td> 0.000</td> <td>    0.131</td> <td>    0.315</td>\n",
       "</tr>\n",
       "<tr>\n",
       "  <th>x3</th> <td>    0.5010</td> <td>    0.080</td> <td>    6.237</td> <td> 0.000</td> <td>    0.342</td> <td>    0.660</td>\n",
       "</tr>\n",
       "</table>\n",
       "<table class=\"simpletable\">\n",
       "<tr>\n",
       "  <th>Omnibus:</th>       <td> 4.662</td> <th>  Durbin-Watson:     </th> <td>   2.201</td>\n",
       "</tr>\n",
       "<tr>\n",
       "  <th>Prob(Omnibus):</th> <td> 0.097</td> <th>  Jarque-Bera (JB):  </th> <td>   4.098</td>\n",
       "</tr>\n",
       "<tr>\n",
       "  <th>Skew:</th>          <td> 0.481</td> <th>  Prob(JB):          </th> <td>   0.129</td>\n",
       "</tr>\n",
       "<tr>\n",
       "  <th>Kurtosis:</th>      <td> 3.243</td> <th>  Cond. No.          </th> <td>    1.74</td>\n",
       "</tr>\n",
       "</table><br/><br/>Warnings:<br/>[1] Standard Errors assume that the covariance matrix of the errors is correctly specified."
      ],
      "text/plain": [
       "<class 'statsmodels.iolib.summary.Summary'>\n",
       "\"\"\"\n",
       "                                 OLS Regression Results                                \n",
       "=======================================================================================\n",
       "Dep. Variable:                      y   R-squared (uncentered):                   0.430\n",
       "Model:                            OLS   Adj. R-squared (uncentered):              0.413\n",
       "Method:                 Least Squares   F-statistic:                              24.42\n",
       "Date:                Fri, 26 Jun 2020   Prob (F-statistic):                    7.44e-12\n",
       "Time:                        17:44:46   Log-Likelihood:                         -34.305\n",
       "No. Observations:                 100   AIC:                                      74.61\n",
       "Df Residuals:                      97   BIC:                                      82.42\n",
       "Df Model:                           3                                                  \n",
       "Covariance Type:            nonrobust                                                  \n",
       "==============================================================================\n",
       "                 coef    std err          t      P>|t|      [0.025      0.975]\n",
       "------------------------------------------------------------------------------\n",
       "x1             0.1783      0.053      3.364      0.001       0.073       0.283\n",
       "x2             0.2230      0.046      4.818      0.000       0.131       0.315\n",
       "x3             0.5010      0.080      6.237      0.000       0.342       0.660\n",
       "==============================================================================\n",
       "Omnibus:                        4.662   Durbin-Watson:                   2.201\n",
       "Prob(Omnibus):                  0.097   Jarque-Bera (JB):                4.098\n",
       "Skew:                           0.481   Prob(JB):                        0.129\n",
       "Kurtosis:                       3.243   Cond. No.                         1.74\n",
       "==============================================================================\n",
       "\n",
       "Warnings:\n",
       "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n",
       "\"\"\""
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 对结果使用 summary 方法可以打印模型的详细诊断结果\n",
    "results.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>col0</th>\n",
       "      <th>col1</th>\n",
       "      <th>col2</th>\n",
       "      <th>y</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>-0.129468</td>\n",
       "      <td>-1.212753</td>\n",
       "      <td>0.504225</td>\n",
       "      <td>0.427863</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.302910</td>\n",
       "      <td>-0.435742</td>\n",
       "      <td>-0.254180</td>\n",
       "      <td>-0.673480</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>-0.328522</td>\n",
       "      <td>-0.025302</td>\n",
       "      <td>0.138351</td>\n",
       "      <td>-0.090878</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>-0.351475</td>\n",
       "      <td>-0.719605</td>\n",
       "      <td>-0.258215</td>\n",
       "      <td>-0.489494</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1.243269</td>\n",
       "      <td>-0.373799</td>\n",
       "      <td>-0.522629</td>\n",
       "      <td>-0.128941</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       col0      col1      col2         y\n",
       "0 -0.129468 -1.212753  0.504225  0.427863\n",
       "1  0.302910 -0.435742 -0.254180 -0.673480\n",
       "2 -0.328522 -0.025302  0.138351 -0.090878\n",
       "3 -0.351475 -0.719605 -0.258215 -0.489494\n",
       "4  1.243269 -0.373799 -0.522629 -0.128941"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 这里的参数名为通用名 x1, x2等等\n",
    "# 假设所有的模型参数都在一个 DataFrame 中：\n",
    "data = pd.DataFrame(X, columns=['col0', 'col1', 'col2'])\n",
    "\n",
    "data['y'] = y\n",
    "\n",
    "data[:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Intercept    0.033559\n",
       "col0         0.176149\n",
       "col1         0.224826\n",
       "col2         0.514808\n",
       "dtype: float64"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 现在，使用 statsmodels 的公式 API和 Patsy的公式字符串：\n",
    "results = smf.ols('y ~ col0 + col1 + col2', data=data).fit()\n",
    "\n",
    "results.params"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Intercept    0.952188\n",
       "col0         3.319754\n",
       "col1         4.850730\n",
       "col2         6.303971\n",
       "dtype: float64"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "results.tvalues"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0   -0.002327\n",
       "1   -0.141904\n",
       "2    0.041226\n",
       "3   -0.323070\n",
       "4   -0.100535\n",
       "dtype: float64"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 观察下 statsmodels 是如何返回 Series 结果的， 附带有 DataFrame 的列名。\n",
    "#  当使用公式和 pandas 对象时，不需要使用 add_constant。\n",
    "\n",
    "# 给出一个样本外数据，可以根据估计的模型参数计算预测值：\n",
    "results.predict(data[:5])\n",
    "\n",
    "# statsmodels 的线性模型结果还有其它的分析、 诊断和可视化工具。\n",
    "# 除了普通最小二乘模型， 还有其它的线性模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Anaconda\\lib\\site-packages\\statsmodels\\tsa\\ar_model.py:691: FutureWarning: \n",
      "statsmodels.tsa.AR has been deprecated in favor of statsmodels.tsa.AutoReg and\n",
      "statsmodels.tsa.SARIMAX.\n",
      "\n",
      "AutoReg adds the ability to specify exogenous variables, include time trends,\n",
      "and add seasonal dummies. The AutoReg API differs from AR since the model is\n",
      "treated as immutable, and so the entire specification including the lag\n",
      "length must be specified when creating the model. This change is too\n",
      "substantial to incorporate into the existing AR api. The function\n",
      "ar_select_order performs lag length selection for AutoReg models.\n",
      "\n",
      "AutoReg only estimates parameters using conditional MLE (OLS). Use SARIMAX to\n",
      "estimate ARX and related models using full MLE via the Kalman Filter.\n",
      "\n",
      "To silence this warning and continue using AR until it is removed, use:\n",
      "\n",
      "import warnings\n",
      "warnings.filterwarnings('ignore', 'statsmodels.tsa.ar_model.AR', FutureWarning)\n",
      "\n",
      "  warnings.warn(AR_DEPRECATION_WARN, FutureWarning)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([-0.00616093,  0.78446347, -0.40847891, -0.01364148,  0.01496872,\n",
       "        0.01429462])"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 估计时间序列过程\n",
    "\n",
    "# statsmodels 的另一模型类是进行时间序列分析， 包括自回归过程、 卡尔曼滤波和其它态空间模型， 和多元自回归模型。\n",
    "\n",
    "# 用自回归结构和噪声来模拟一些时间序列数据：\n",
    "init_x = 4\n",
    "\n",
    "import random\n",
    "\n",
    "values = [init_x, init_x]\n",
    "N = 1000\n",
    "\n",
    "b0 = 0.8\n",
    "b1 = -0.4\n",
    "noise = dnorm(0, 0.1, N)\n",
    "for i in range(N):\n",
    "    new_x = values[-1] * b0 + values[-2] * b1 + noise[i]\n",
    "    values.append(new_x)\n",
    "\n",
    "\n",
    "# 这个数据有 AR(2)结构（两个延迟）,参数是 0.8 和 -0.4。\n",
    "# 拟合 AR模型时， 可能不知道滞后项的个数， 因此可以用较多的滞后量来拟合这个模型：\n",
    "MAXLAGS = 5\n",
    "\n",
    "model = sm.tsa.AR(values)\n",
    "\n",
    "results = model.fit(MAXLAGS)\n",
    "\n",
    "# 结果中的估计参数首先是截距， 其次是前两个参数的估计值：\n",
    "results.params\n",
    "\n",
    "# 更多的细节以及如何解释结果超出了范围， 可以通过 statsmodels 文档学习更多"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>PassengerId</th>\n",
       "      <th>Survived</th>\n",
       "      <th>Pclass</th>\n",
       "      <th>Name</th>\n",
       "      <th>Sex</th>\n",
       "      <th>Age</th>\n",
       "      <th>SibSp</th>\n",
       "      <th>Parch</th>\n",
       "      <th>Ticket</th>\n",
       "      <th>Fare</th>\n",
       "      <th>Cabin</th>\n",
       "      <th>Embarked</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>Braund, Mr. Owen Harris</td>\n",
       "      <td>male</td>\n",
       "      <td>22.0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>A/5 21171</td>\n",
       "      <td>7.2500</td>\n",
       "      <td>NaN</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>Cumings, Mrs. John Bradley (Florence Briggs Th...</td>\n",
       "      <td>female</td>\n",
       "      <td>38.0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>PC 17599</td>\n",
       "      <td>71.2833</td>\n",
       "      <td>C85</td>\n",
       "      <td>C</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>Heikkinen, Miss. Laina</td>\n",
       "      <td>female</td>\n",
       "      <td>26.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>STON/O2. 3101282</td>\n",
       "      <td>7.9250</td>\n",
       "      <td>NaN</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>Futrelle, Mrs. Jacques Heath (Lily May Peel)</td>\n",
       "      <td>female</td>\n",
       "      <td>35.0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>113803</td>\n",
       "      <td>53.1000</td>\n",
       "      <td>C123</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>Allen, Mr. William Henry</td>\n",
       "      <td>male</td>\n",
       "      <td>35.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>373450</td>\n",
       "      <td>8.0500</td>\n",
       "      <td>NaN</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   PassengerId  Survived  Pclass  \\\n",
       "0            1         0       3   \n",
       "1            2         1       1   \n",
       "2            3         1       3   \n",
       "3            4         1       1   \n",
       "4            5         0       3   \n",
       "\n",
       "                                                Name     Sex   Age  SibSp  \\\n",
       "0                            Braund, Mr. Owen Harris    male  22.0      1   \n",
       "1  Cumings, Mrs. John Bradley (Florence Briggs Th...  female  38.0      1   \n",
       "2                             Heikkinen, Miss. Laina  female  26.0      0   \n",
       "3       Futrelle, Mrs. Jacques Heath (Lily May Peel)  female  35.0      1   \n",
       "4                           Allen, Mr. William Henry    male  35.0      0   \n",
       "\n",
       "   Parch            Ticket     Fare Cabin Embarked  \n",
       "0      0         A/5 21171   7.2500   NaN        S  \n",
       "1      0          PC 17599  71.2833   C85        C  \n",
       "2      0  STON/O2. 3101282   7.9250   NaN        S  \n",
       "3      0            113803  53.1000  C123        S  \n",
       "4      0            373450   8.0500   NaN        S  "
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# scikit-learn介绍\n",
    "\n",
    "# scikit-learn 是一个广泛使用、 用途多样的 Python 机器学习库。 \n",
    "#     它包含多种标准监督和非监督机器学习方法和模型选择和评估、 数据转换、 数据加载和模型持久化工具。 \n",
    "# 这些模型可以用于分类、 聚合、 预测和其它任务。\n",
    "\n",
    "# 机器学习方面的学习和应用 scikit-learn 和 TensorFlow 解决实际问题的线上和纸质资料很多\n",
    "\n",
    "# 介绍 scikit-learn API的风格。\n",
    "# scikit-learn 并没有和 pandas深度结合， 但是有些第三方包在开发中。 尽管如此， pandas 非常适合在模型拟合前处理数据集\n",
    "\n",
    "# 举个例子， 用一个 Kaggle 竞赛的经典数据集， 关于泰坦尼克号乘客的生还率\n",
    "# 用 pandas 加载 测试和训练数据集\n",
    "\n",
    "dataset_path = './../dataset/'\n",
    "\n",
    "train = pd.read_csv(dataset_path + 'titanic/train.csv')\n",
    "test = pd.read_csv(dataset_path + 'titanic/test.csv')\n",
    "\n",
    "train.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PassengerId      0\n",
       "Survived         0\n",
       "Pclass           0\n",
       "Name             0\n",
       "Sex              0\n",
       "Age            177\n",
       "SibSp            0\n",
       "Parch            0\n",
       "Ticket           0\n",
       "Fare             0\n",
       "Cabin          687\n",
       "Embarked         2\n",
       "dtype: int64"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# statsmodels 和 scikit-learn 通常不能接收缺失数据，\n",
    "# 因此要查看列是否包含缺失值：\n",
    "train.isnull().sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PassengerId      0\n",
       "Pclass           0\n",
       "Name             0\n",
       "Sex              0\n",
       "Age             86\n",
       "SibSp            0\n",
       "Parch            0\n",
       "Ticket           0\n",
       "Fare             1\n",
       "Cabin          327\n",
       "Embarked         0\n",
       "dtype: int64"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test.isnull().sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 3.,  0., 22.],\n",
       "       [ 1.,  1., 38.],\n",
       "       [ 3.,  1., 26.],\n",
       "       [ 1.,  1., 35.],\n",
       "       [ 3.,  0., 35.]])"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 在统计和机器学习的例子中， 根据数据中的特征， 一个典型的任务是预测乘客能否生还。 \n",
    "#  模型先在训练数据集中拟合， 然后用样本外测试数据集评估。\n",
    "\n",
    "# 想用年龄作为预测值， 但是它包含缺失值。 \n",
    "# 缺失数据补全的方法有多种， 用的是一种简单方法， 用训练数据集的中位数补全两个表的空值\n",
    "impute_value = train['Age'].median()\n",
    "\n",
    "train['Age'] = train['Age'].fillna(impute_value)\n",
    "\n",
    "test['Age'] = test['Age'].fillna(impute_value)\n",
    "\n",
    "# 现在需要指定模型。增加了一个列 IsFemale， 作为“Sex”列的编码：\n",
    "train['IsFemale'] = (train['Sex'] == 'female').astype(int)\n",
    "\n",
    "test['IsFemale'] = (test['Sex'] == 'female').astype(int)\n",
    "\n",
    "# 然后， 确定一些模型变量， 并创建 NumPy 数组：\n",
    "predictors = ['Pclass', 'IsFemale', 'Age']\n",
    "\n",
    "X_train = train[predictors].values\n",
    "\n",
    "X_test = test[predictors].values\n",
    "\n",
    "y_train = train['Survived'].values\n",
    "\n",
    "X_train[:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 1, 1, 1, 0], dtype=int64)"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train[:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,\n",
       "                   intercept_scaling=1, l1_ratio=None, max_iter=100,\n",
       "                   multi_class='auto', n_jobs=None, penalty='l2',\n",
       "                   random_state=None, solver='lbfgs', tol=0.0001, verbose=0,\n",
       "                   warm_start=False)"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 不能保证这是一个好模型， 但它的特征都符合\n",
    "#   用 scikit-learn 的 LogisticRegression 模型，\n",
    "# 创建一个模型实例：\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "\n",
    "model = LogisticRegression()\n",
    "\n",
    "# 与 statsmodels 类似，可以用模型的 fit 方法， 将它拟合到训练数据：\n",
    "model.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 0, 0, 0, 1, 0, 1, 0, 1, 0], dtype=int64)"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 可以用 model.predict， 对测试数据进行预测：\n",
    "y_predict = model.predict(X_test)\n",
    "\n",
    "y_predict[:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 如果有测试数据集的真实值，可以计算准确率或其它错误度量值：\n",
    "# (y_true == y_predict).mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LogisticRegressionCV(Cs=10, class_weight=None, cv=None, dual=False,\n",
       "                     fit_intercept=True, intercept_scaling=1.0, l1_ratios=None,\n",
       "                     max_iter=100, multi_class='auto', n_jobs=None,\n",
       "                     penalty='l2', random_state=None, refit=True, scoring=None,\n",
       "                     solver='lbfgs', tol=0.0001, verbose=0)"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 在实际中， 模型训练经常有许多额外的复杂因素。 \n",
    "# 许多模型有可以调节的参数， 有些方法（比如交叉验证）可以用来进行参数调节， 避免对训练数据过拟合\n",
    "#  这通常可以提高预测性或对新数据的健壮性。\n",
    "\n",
    "# 交叉验证通过分割训练数据来模拟样本外预测。\n",
    "# 基于模型的精度得分（比如均方差） ，可以对模型参数进行网格搜索。\n",
    "# 有些模型， 如 logistic 回归， 有内置的交叉验证的估计类。\n",
    "\n",
    "# 例如，logisticregressioncv 类可以用一个参数指定网格搜索对模型的正则化参数C 的粒度\n",
    "from sklearn.linear_model import LogisticRegressionCV\n",
    "\n",
    "model_cv = LogisticRegressionCV(10)\n",
    "\n",
    "model_cv.fit(X_train, y_train)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0.77578475, 0.79820628, 0.77578475, 0.78828829])"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 要手动进行交叉验证， 可以使用 cross_val_score 帮助函数， 它可以处理数据分割\n",
    "#  例如， 要交叉验证带有四个不重叠训练数据的模型， 可以这样做\n",
    "\n",
    "from sklearn.model_selection import cross_val_score\n",
    "\n",
    "model = LogisticRegression(C=10)\n",
    "\n",
    "scores = cross_val_score(model, X_train, y_train, cv=4)\n",
    "\n",
    "scores\n",
    "\n",
    "# 默认的评分指标取决于模型本身， 但是可以明确指定一个评分\n",
    "#    交叉验证过的模型需要更长时间来训练， 但会有更高的模型性能。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 继续学习\n",
    "\n",
    "# 介绍了一些 Python 建模库的表面内容， 现在有越来越多的框架用于各种统计和机器学习，\n",
    "#      它们都是用 Python 或 Python用户界面实现的\n",
    "\n",
    "\n",
    "# 这本书的重点是 数据规整， 有其它的书是关注 建模 和 数据科学工具 的\n",
    "#    其中优秀的有：\n",
    "\n",
    "# Andreas Mueller and Sarah Guido (O’Reilly)的 《Introduction to Machine Learning with Python》\n",
    "# Jake VanderPlas (O’Reilly)的 《Python Data Science Handbook》\n",
    "# Joel Grus (O’Reilly) 的 《Data Science from Scratch: First Principles》\n",
    "# Sebastian Raschka (Packt Publishing) 的《Python Machine Learning》\n",
    "# Aurélien Géron (O’Reilly) 的《Hands-On Machine Learning with Scikit-Learn and TensorFlow》\n",
    "\n",
    "# 虽然书是学习的好资源， 但是随着底层开源软件的发展， 书的内容会过时\n",
    "#    最好是不断熟悉各种统计和机器学习框架的文档， 学习最新的功能和API"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
